<template>
  <div class="bs-custom-components">
    <div class="bs-custom-component-header">
      <div class="left-title">
        <div class="logo-wrap item-wrap">
          <img
            class="menu-img"
            src="../BigScreenDesign/images/app.png"
            alt="返回"
            @click="backManagement"
          >
          <span class="logo-text name-span">{{ form.name }}</span>
        </div>
      </div>
      <div class="right-btn-wrap">
        <CusBtn
          :loading="loading"
          @click="save"
        >
          保存
        </CusBtn>
      </div>
    </div>
    <div class="bs-custom-component-content">
      <div class="bs-custom-component-content-code">
        <div class="left-vue-code component-code">
          <div class="code-tab-header">
            <div class="code-tab-left">
              <div class="code-tab">
                组件模板
              </div>
              <div
                class="code-tab-btn"
                @click="change('echart')"
              >
                echarts组件
              </div>
              <div
                class="code-tab-btn"
                @click="change('g2plot')"
              >
                G2Plot组件
              </div>
              <div
                class="code-tab-btn"
                @click="change('native')"
              >
                原生组件
              </div>
              <div
                class="code-tab-btn"
                @click="change('3DEchart')"
              >
                3D组件
              </div>
            </div>
            <!-- <div class="upload-btn">
              <CusBtn @click="upload('vueContent')">
                上传
              </CusBtn>
            </div> -->
          </div>
          <div class="code-tab-content">
            <!-- <MonacoEditor
              ref="vueContent"
              v-model="form.vueContent"
              class="editor"
              language="html"
            /> -->
            <codemirror
              v-model="form.vueContent"
              :options="vueOptions"
            />
          </div>
        </div>
        <div class="right-setting-code component-code">
          <div class="code-tab-header">
            <div class="code-tab">
              组件配置
            </div>
            <!-- <div class="upload-btn">
              <CusBtn @click="upload('settingContent')">
                上传
              </CusBtn>
            </div> -->
          </div>
          <div class="code-tab-content">
            <!-- <MonacoEditor
              ref="settingContent"
              v-model="form.settingContent"
              class="editor"
              language="javascript"
            /> -->
            <codemirror
              v-model="form.settingContent"
              :options="settingOptions"
            />
          </div>
        </div>
      </div>
      <div class="bs-custom-component-content-preview">
        <div class="bs-preview-inner">
          <div class="code-tab-header">
            <div class="code-tab">
              效果预览
            </div>
            <div class="upload-btn">
              <CusBtn
                :loading="loading"
                @click.native="createdImg()"
              >
                生成图片
              </CusBtn>
            </div>
          </div>
          <BizComponentPreview
            :vue-content="form.vueContent"
            :setting-content="form.settingContent"
          />
        </div>
      </div>
      <!-- 通过计算属性发现accept有问题 -->
      <input
        ref="vueContentFile"
        style="display: none"
        type="file"
        name="file"
        accept=".vue"
        @change="handleBatchUpload"
      >
      <input
        ref="settingContentFile"
        style="display: none"
        type="file"
        name="file"
        accept=".js"
        @change="handleBatchUpload"
      >
    </div>
  </div>
</template>
<script>
import { toJpeg } from 'html-to-image'
import CusBtn from 'data-room-ui/BigScreenDesign/BtnLoading'
// import MonacoEditor from 'data-room-ui/MonacoEditor'
import BizComponentPreview from './Preview'
import { getBizComponentInfo, updateBizComponent } from 'data-room-ui/js/api/bigScreenApi'
import { defaultSettingContent, defaultVueContent } from './config/defaultBizConfig'
import { defaultEchartsSettingContent, defaultEchartsVueContent } from './config/defaultEchartsConfig'
import { defaultG2SettingContent, defaultG2VueContent } from './config/defaultG2Config'
import { codemirror } from 'vue-codemirror'
import 'codemirror/lib/codemirror.css'
import 'codemirror/theme/material-darker.css'
import 'codemirror/addon/selection/active-line.js'
import 'codemirror/mode/vue/vue.js'

import {
  showSize,
  compressImage
  // dataURLtoBlob,
  // translateBlobToBase64
} from 'data-room-ui/js/utils/compressImg'
// import * as imageConversion from 'image-conversion'

export default {
  name: 'BizComponentDesign',
  components: {
    CusBtn,
    // MonacoEditor,
    codemirror,
    BizComponentPreview
  },
  props: {},
  data () {
    return {
      initialCoverPicture: '',
      form: {
        name: '',
        coverPicture: '',
        settingContent: '',
        vueContent: ''
      },
      currentContentType: 'vueContent',
      loading: false,
      vueOptions: {
        foldGutter: true,
        lineWrapping: true,
        gutters: [
          'CodeMirror-linenumbers',
          'CodeMirror-foldgutter',
          'CodeMirror-lint-markers'
        ],
        theme: 'material-darker',
        tabSize: 4,
        lineNumbers: true,
        line: true,
        indentWithTabs: true,
        smartIndent: true,
        autofocus: false,
        matchBrackets: true,
        mode: 'text/x-vue',
        hintOptions: {
          completeSingle: false
        },
        lint: true
      },
      settingOptions: {
        foldGutter: true,
        lineWrapping: true,
        gutters: [
          'CodeMirror-linenumbers',
          'CodeMirror-foldgutter',
          'CodeMirror-lint-markers'
        ],
        theme: 'material-darker',
        tabSize: 4,
        lineNumbers: true,
        line: true,
        indentWithTabs: true,
        smartIndent: true,
        autofocus: false,
        matchBrackets: true,
        mode: 'text/javascript',
        hintOptions: {
          completeSingle: false
        },
        lint: true
      }
    }
  },
  computed: {
  },
  mounted () {
    this.getBizComponentInfo()
  },
  methods: {
    getBizComponentInfo () {
      const code = this.$route.query.code
      const type = this.$route.query.type
      if (code) {
        getBizComponentInfo(code).then(data => {
          this.initialCoverPicture = data.coverPicture || ''
          if (type && type === 'g2plot') {
            this.form = {
              ...data,
              name: data.name,
              coverPicture: data.coverPicture,
              settingContent: data.settingContent || defaultG2SettingContent,
              vueContent: data.vueContent || defaultG2VueContent
            }
          } else if (type && type === 'echart') {
            this.form = {
              ...data,
              name: data.name,
              coverPicture: data.coverPicture,
              settingContent: data.settingContent || defaultEchartsSettingContent,
              vueContent: data.vueContent || defaultEchartsVueContent
            }
          } else {
            this.form = {
              ...data,
              name: data.name,
              coverPicture: data.coverPicture,
              settingContent: data.settingContent || defaultSettingContent,
              vueContent: data.vueContent || defaultVueContent
            }
          }

          // this.$refs.vueContent.editor.setValue(this.form.vueContent)
          // this.$refs.settingContent.editor.setValue(this.form.settingContent)
        })
      }
    },
    changeTemp (val) {
      if (val === 'g2plot') {
        this.form.settingContent = defaultG2SettingContent
        this.form.vueContent = defaultG2VueContent
      } else if (val === 'native') {
        this.form.settingContent = defaultSettingContent
        this.form.vueContent = defaultVueContent
      } else if (val === 'echart') {
        this.form.settingContent = defaultEchartsSettingContent
        this.form.vueContent = defaultEchartsVueContent
      }
    },
    change (val) {
      if (val === '3DEchart') {
        return this.$confirm('开发中。。。。', '提示', {
          distinguishCancelAndClose: true,
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          cancelButtonClass: 'cancel-btn',
          type: 'warning',
          customClass: 'bs-el-message-box'
        }).then(() => {
        }).catch((action) => {
        })
      }
      this.$confirm('确定替换为选中模板吗？未保存的代码将被覆盖！', '提示', {
        distinguishCancelAndClose: true,
        confirmButtonText: '确定',
        showCancelButton: false,
        cancelButtonClass: 'cancel-btn',
        type: 'warning',
        customClass: 'bs-el-message-box'
      }).then(() => {
        this.changeTemp(val)
      }).catch((action) => {

      })
    },
    // upload (type) {
    //   this.currentContentType = type
    //   this.$refs[`${this.currentContentType}File`].click()
    // },
    handleBatchUpload (source) {
      const file = source.target.files
      const reader = new FileReader() // 新建一个FileReader
      reader.readAsText(file[0], 'UTF-8') // 读取文件

      reader.onload = (event) => {
        const sileString = event.target.result // 读取文件内容
        this.form[this.currentContentType] = sileString
        // input通过onchange事件来触发js代码的，由于两次文件是重复的，所以这个时候onchange事件是没有触发到的，所以需要手动清空input的值
        source.target.value = ''
      }
    },
    backManagement () {
      // 给出一个确认框提示，提示如下确定返回主页面吗？未保存的配置将会丢失。3个按钮 ：  留在页面 、离开页面、保存后离开页面
      this.$confirm('确定返回主页面吗？未保存的配置将会丢失。', '提示', {
        distinguishCancelAndClose: true,
        confirmButtonText: '保存后离开页面',
        cancelButtonText: '离开页面',
        cancelButtonClass: 'cancel-btn',
        type: 'warning',
        customClass: 'bs-el-message-box'
      }).then(() => {
        this.save(true)
      }).catch((action) => {
        if (action === 'cancel') {
          this.pageJump()
        }
      })
    },
    async save (pageJump = false) {
      this.loading = true
      let dataUrl = ''
      const node = document.querySelector('.remote-preview-inner-wrap')
      // 获取node下的第一个子节点
      const childrenNode = node.children[0]
      try {
        dataUrl = await toJpeg(childrenNode, { quality: 0.2 })
      } catch (error) {
        console.info(error)
      }
      if (dataUrl) {
        if (showSize(dataUrl) > 200) {
          // const url = dataURLtoBlob(dataUrl)
          // 压缩到500KB,这里的500就是要压缩的大小,可自定义
          // imageConversion.compressAccurately(
          //   url,
          //   {
          //     size: 200, // 图片大小压缩到100kb
          //     width: 1280, // 宽度压缩到1280
          //     height: 720 // 高度压缩到720
          //   }
          // ).then((res) => {
          //   translateBlobToBase64(res, (e) => {
          //     this.form.coverPicture = e.result
          //   })
          // })
          this.$message.info('由于封面图片过大，进行压缩中')
          this.form.coverPicture = await compressImage(dataUrl, { width: 1280, height: 720, size: 400, quality: 1 })
        } else {
          this.form.coverPicture = dataUrl
        }

      } else {
        this.$message.warning('保存封面失败，将使用上次保存的封面')
        this.form.coverPicture = this.initialCoverPicture
      }

      updateBizComponent(this.form).then(() => {
        this.$message({
          message: '保存成功',
          type: 'success',
          duration: 800,
          onClose: () => {
            // 此处写提示关闭后需要执行的函数
            if (pageJump) {
              this.pageJump()
            }
          }
        })
        this.loading = false
      }).catch((error) => {
        console.info(error)
        this.loading = false
      })
    },
    createdImg () {
      this.loading = true
      const node = document.querySelector('.remote-preview-inner-wrap')
      // 获取node下的第一个子节点
      const childrenNode = node.children[0]
      // 为childrenNode添加一个背景颜色
      childrenNode.style.backgroundColor = 'var(--bs-background-1)'
      toJpeg(childrenNode)
        .then((dataUrl) => {
          const link = document.createElement('a')
          link.download = `${this.form.name}.png`
          link.href = dataUrl
          link.click()
          link.addEventListener('click', () => {
            link.remove()
          })
          this.loading = false
        })
        .catch((error) => {
          console.info(error)
          this.loading = false
          // 判断的error.currentTarget是img标签，如果是的，就弹出消息说是图片跨域
          // 确认框
          this.$confirm('图片、视频资源跨域导致使用toDataURL API生成图片失败，请将资源上传到资源库，然后在组件中使用资源库中的图片资源，确保没有跨域问题。', '提示', {
            confirmButtonText: '确定',
            showCancelButton: false,
            type: 'warning',
            customClass: 'bs-el-message-box'
          }).then(() => { }).catch(() => { })
        })
    },
    pageJump () {
      const data = { componentsManagementType: 'bizComponent' }
      this.$router.app.$options.globalData = data // 将数据存储在全局变量中
      this.$router.push({ path: window.BS_CONFIG?.routers?.componentUrl || '/big-screen-components' })
    }
  }
}
</script>

<style lang="scss" scoped>
.bs-custom-components {
  position: absolute;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100vh;
  color: var(--bs-el-text);
  background: var(--bs-background-2);
  overflow: hidden;

  >* {
    box-sizing: border-box;
  }

  .bs-custom-component-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 50px;
    padding: 0 16px;
    border-bottom: 4px solid var(--bs-background-1);
    background: var(--bs-background-2);

    .left-title {
      font-size: 16px;
      color: var(--bs-el-title);

      .logo-wrap {
        display: flex;
        align-items: center;
      }

      .menu-img {
        width: 18px;
        height: 18px;
        margin-right: 15px;
        margin-left: 9px;
        cursor: pointer;
      }
    }

    .right-btn-wrap {
      display: flex;
      align-items: center;
      height: 100%;
    }
  }

  .bs-custom-component-content {
    flex: 1;
    background: var(--bs-background-2);
    display: flex;
    flex-direction: column;

    .bs-custom-component-content-code {
      display: flex;
      justify-content: space-between;
      width: 100%;
      height: 354px;
      padding: 5px 16px;

      .left-vue-code {
        width: 60%;
        height: 100%;
        /* background: var(--bs-background-1); */
      }

      .right-setting-code {
        width: calc(40% - 16px);
        height: 100%;
        /* background: var(--bs-background-1); */
      }

      .component-code {
        .code-tab-header {
          display: flex;
          align-items: center;
          justify-content: space-between;
          height: 40px;

          .code-tab-left {
            height: 100%;
            width: 450px;
            display: flex;
            flex-direction: row;
            align-items: center;
            justify-content: space-between;

            .code-tab-btn {
              // width: 90px;
              cursor: pointer;
              text-align: center;
            }

            .code-tab {
              font-size: 14px;
              align-items: center;
              justify-content: center;
              width: 120px;
              height: 100%;
              color: var(--bs-el-title);
              background: var(--bs-background-1);
            }
          }

          .code-tab {
            font-size: 14px;
            display: flex;
            align-items: center;
            justify-content: center;
            width: 120px;
            height: 100%;
            color: var(--bs-el-title);
            background: var(--bs-background-1);
          }
        }

        .code-tab-content {
          height: calc(100% - 88px);
          background: var(--bs-background-1);
        }
      }
    }

    .bs-custom-component-content-preview {
      flex: 1;
      width: 100%;
      height: 50%;
      padding: 0 16px 16px;

      .bs-preview-inner {
        width: 100%;
        height: 100%;
        background: var(--bs-background-1);
        position: relative;

        .code-tab-header {
          height: 40px;
          display: flex;
          flex-direction: row;
          align-items: center;
          background-color: var(--bs-background-2);

          .code-tab {
            font-size: 14px;
            align-items: center;
            justify-content: center;
            display: flex;
            width: 120px;
            margin-right: 20px;
            height: 100%;
            color: var(--bs-el-title);
            background: var(--bs-background-1);
          }
        }
      }
    }
  }
}
</style>
<style>
.cm-s-material-darker.CodeMirror,
.cm-s-material-darker .CodeMirror-gutters {
  background: var(--bs-background-1) !important;
}

.CodeMirror-scroll {
  background-color: var(--bs-background-1) !important;
}

.CodeMirror-gutters {
  border-right: 1px solid var(--bs-background-1) !important;
  background-color: var(--bs-background-1) !important;
}

.CodeMirror-vscrollbar {
  right: 0;
  top: 0;
  overflow-x: hidden;
  overflow-y: scroll;
  margin-right: 4px;
}

/* Webkit浏览器滚动条样式 */
.CodeMirror-vscrollbar::-webkit-scrollbar {
  width: 6px;
  /* 滚动条宽度 */
}

.CodeMirror-vscrollbar::-webkit-scrollbar-thumb {
  background-color: #444851;
  /* 滚动条滑块颜色 */
  border-radius: 4px;
  /* 滚动条滑块圆角 */
}

.CodeMirror-vscrollbar::-webkit-scrollbar-thumb:hover {
  background-color: #444851;
  /* 滚动条滑块悬停时颜色 */
}

/* Firefox和新版Chrome浏览器滚动条样式 */
.CodeMirror-vscrollbar {
  scrollbar-width: thin;
  /* 滚动条宽度 */
  scrollbar-color: #444851 #444851;
  /* 滚动条颜色 */
}

.CodeMirror-vscrollbar::-webkit-scrollbar-thumb {
  background-color: #444851;
  /* 滚动条滑块颜色 */
}

.CodeMirror-vscrollbar::-webkit-scrollbar-thumb:hover {
  background-color: #444851;
  /* 滚动条滑块悬停时颜色 */
}
</style>
